//
// Created by wjf82 on 2020/6/7.
//

#ifndef NEW_SUDO_SUDOKU_NEW_H
#define NEW_SUDO_SUDOKU_NEW_H

#include <stdio.h>
#include "config.h"

typedef struct {
    int x;
    int y;
}Local;

//查找空单元并返回位置
Local find_zero_local(int arr[][MAXNU]);

//判断是否有空单元
bool had_zero_uint(int arr[][MAXNU]);

//输出数独
void output_sudoku(int arr_sudoku[][MAXNU]);

//根据所在行判断是否满足没有重复元素的要求
bool is_sudoku_line(int arr[][MAXNU]);

//根据所在列判断是否满足没有重复元素的要求
bool is_sudoku_row(int arr[][MAXNU]);

//获得宫格组的二维数组
void get_square_arr(int arr[][MAXNU],int res[][MAXNU]);

//获得所在宫格号
int get_square_nu(int x,int y);

//根据所在列判断是否满足没有重复元素的要求
bool is_sudoku_square(int arr[][MAXNU]);

//与标准数组normal做对比求异 结果放在res[]里
void arr_different(const int arr[],const int nor[], int res[]);

//求所在local_x行的解集
void resolve_sudoku_line(int arr[][MAXNU],int local_x,int res[]);

//求所在local_y列的解集
void resolve_sudoku_row(int arr[][MAXNU],int local_y,int res[]);

//求所在square_n组的解集
void resolve_sudoku_square(int arr[][MAXNU], int square_n,int res[]);

//求x,y坐标下的可能解集
void resolve_sudoku(int arr[][MAXNU],int x,int y,int res[]);

//是否能满足数独的四个条件
//是否能满足数独的四个条件
//1.没有空单元 2.行元素各不同 3.列元素各不同 4.组元素各不同
bool is_sudoku(int arr[][MAXNU]);

//判断解集数组是否为空
bool is_nop_arr(const int arr[]);

//删除数组中的第一个元素
void delete_arr_first(int arr[]);

//打印一个一维数组
void print_arr(int arr[]);

//找出所有空单元 将坐标记录到res[n][1]和res[n][2]中 res[n][0]标记是否为空
int find_all_zero(int arr[][MAXNU],int res[][3]);

//根据填入空单元的个数返回坐标
Local count_find_local(int arr[][3],int count);

//求所有空单元的解集 对应第N个 存放在[81][9]的二维数组里
void resolve_all_arr(int arr[][MAXNU],int res[][MAXNU]);

//打印一个m行n列的数组
void outprint_arr(int m,int n,int arr[m][n]);

//删除所有空单元解集的n行的第一个解 并恢复其后的其他解 将结果储存在res[][]中
void delete_one_key(int n,int arr[][MAXNU],int res[][MAXNU]);

//将一个一维数组写入二维数组的第n行
void write_one_to_two(int n,const int arr[MAXNU],int res[][MAXNU]);

//将第n行的二维数组写入一维数组
void write_two_to_one(int n,int arr[][MAXNU],int res[MAXNU]);

//根据坐标返回空坐标的序号
int local_find_count(int x,int y,int arr[][3]);

//输入后求解前判断是否满足数独条件
bool is_input_error(int arr[][MAXNU]);

//更便捷的输入方式
void input_sudoku_new(int arr[][MAXNU]);

#endif //NEW_SUDO_SUDOKU_NEW_H
